Skip to content

feat(claude): validate substitution tokens and record lifecycle contract - #347

Merged
ScriptedAlchemy merged 1 commit into
mainfrom
feat/187-s5-lifecycle
Sep 3, 2026
Merged

feat(claude): validate substitution tokens and record lifecycle contract#347
ScriptedAlchemy merged 1 commit into
mainfrom
feat/187-s5-lifecycle

Conversation

@ScriptedAlchemy

Copy link
Copy Markdown
Owner

Summary

Slice 5 (final) of the #187 Claude parity pass: package/cache/data lifecycle contract, plus an honest substitution-token tightening.

  • New packageLifecycle block in capabilities/claude-2.1.250.json with five rows and dated evidence:
    • nodeDependencyInstall (unavailable) — pins the documented eligible-install contract: package.json + Bun/npm lockfile, frozen installs with --ignore-scripts, 60-second limit, deterministic lockfile precedence (bun.lockbun.lockbnpm-shrinkwrap.jsonpackage-lock.json).
    • yarnPnpmInstallAlternative (unavailable) — Yarn/pnpm lockfiles are documented as skipped (resolution-time hooks bypass --ignore-scripts); the ${CLAUDE_PLUGIN_DATA} hook-install alternative is recorded.
    • pluginCacheLifecycle (unavailable) — cache copy/link semantics, per-resolved-version directories, ~14-day orphan grace/sweep, symlink containment, path escapes plugin directory rejection: all host install-time behavior.
    • pluginPathSubstitution (degraded) — the closed documented substitution table (${CLAUDE_PLUGIN_ROOT}/${CLAUDE_PLUGIN_DATA}/${CLAUDE_PROJECT_DIR} by component/field) is pinned and enforced for structured fields; Skill content and target-native hook documents remain opaque payloads.
    • pluginDataLifecycle (unavailable) — last-scope-uninstall deletion and --keep-data are host-owned.
  • Tightening 1 — MCP stdio cwd: the adapter previously emitted cwd: "${CLAUDE_PLUGIN_ROOT}" as schema-valid future-proofing, but the placeholder table excludes cwd, so the host would receive a literal unsubstituted string. Canonical plugin-root cwd is now omitted (absolute entry path + env anchor already carry the guarantee); token-bearing cwd values are rejected with the new claude.substitution.token.unsupported diagnostic.
  • Tightening 2 — LSP undocumented fields: path tokens in extensionToLanguage, initializationOptions, settings etc. previously passed through unexpanded; now rejected per the documented four-field table (command, args, env, workspaceFolder).
  • Native proofs (Claude Code 2.1.257, isolated config dir): strict validation accepts a plugin root with package.json + package-lock.json without running any install (no node_modules created), and accepts a skills entry symlinked outside the plugin root — proving lockfile handling and symlink containment are install-time, not validation-time.
  • Unified adapter mirrors all five rows via intersectCapabilityStates.

Revisions

Test plan

  • Scoped suites incl. native proofs (AGENT_BUNDLE_NATIVE_HOST_CONTRACTS=1): 412 tests, 0 failed, 0 skipped
  • pnpm -w typecheck
  • pnpm -w lint

Closes the final open section of #187.

@changeset-bot

changeset-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: a3cb102

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
agent-bundle Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-03T00:53:41.128060Z a3cb102 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ScriptedAlchemy
ScriptedAlchemy merged commit 27b3b99 into main Sep 3, 2026
4 checks passed
@ScriptedAlchemy

Copy link
Copy Markdown
Owner Author

Post-merge CI root cause: the cwd tightening here is correct, but path-token-resolver.test.ts retained an integration fixture with cwd: agent-bundle:path:plugin-data. Node 24 therefore failed during artifact compilation before reaching the resolver assertions. #349 moves that plugin-data coverage to documented MCP env substitution and removes the unsupported cwd expectation.

@ScriptedAlchemy
ScriptedAlchemy deleted the feat/187-s5-lifecycle branch September 3, 2026 02:45
ScriptedAlchemy added a commit that referenced this pull request Sep 3, 2026
…the handshake queue (#368)

- packages/agent-bundle/README.md: the Claude adapter no longer emits
  cwd for plugin-root stdio servers (#347 removed it because Claude's
  placeholder table excludes cwd); the README still claimed it did (#47).
- docs/preview-packages.md: the --peerDeps rewrite now applies to the
  optional @agent-bundle/runtime peer declared by agent-bundle, not an
  agent-bundle peer inside the (renamed) runtime package (#45).
- docs/framework-mode.md: restore the rendered-skills (SKILL.tsx) power
  tier and the skills precedence rule (AB4734/AB4735/AB4736, AB3003-AB3005)
  that #150's rewrite dropped from the RFC #63 newcomer doc.
- runtime-client-surface-proxy.test.ts: unit-pin the #23 fix — host
  requests relayed during the App handshake are queued (bounded at 32)
  and flushed on ui/notifications/initialized instead of dropped; only
  the mcp-app-real e2e covered it before.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant